/**
 * ESUI (Enterprise Simple UI)
 * Copyright 2015 Baidu Inc. All rights reserved.
 *
 * @ignore
 * @file 带搜索框的树
 * @author lisijin (ibadplum@gmail.com)
 */
define(
    function (require) {
        var u = require('underscore');
        var eoo = require('eoo');
        var esui = require('esui');
        var Control = require('esui/Control');
        var Tree = require('esui/Tree');
        var TreeStrategy = require('esui/TreeStrategy');
        var SearchBox = require('esui/SearchBox');
        var Button = require('esui/Button');
        var lib = require('esui/lib');
        var $ = require('jquery');
        var painters = require('esui/painters');

        /**
         * 带搜索的树
         *
         * 里面树是esui里的tree,searchbox,link样式的button，想要什么参数直接写到option里穿进去即可。
         * 写了linkContent就有button-link,不写没有。
         * TODO: 现在是人肉写进去的参数，如果参数很多后面可以添加，或者直接copy一个option进去
         * TODO: 有具体需求，可以根据情况来写新的TreeStrategy类，然后适当的改动本控件来处理。例如异步数据处理。
         *
         * @extends Control
         * @constructor
         */
        var SearchTree = eoo.create(
            Control,
            {
                /**
                 * 控件类型，始终为`"SearchTree"`
                 *
                 * @type {string}
                 * @readonly
                 * @override
                 */
                type: 'SearchTree',

                /**
                 * 初始化参数
                 *
                 * @param {Object} [options] 构造函数传入的参数
                 * @protected
                 * @override
                 */
                initOptions: function (options) {
                    var defaults = {
                        datasource: {},
                        cascade: true,
                        buttonPosition: 'right'
                    };
                    var properties = u.extend(defaults, options);
                    this.properties = properties;
                    this.setProperties(properties);
                },

                /**
                 * 初始化DOM结构
                 *
                 * @override
                 * @protected
                 */
                initStructure: function () {
                    u.bind(buildDOMStructure, this)(this.getProperties);
                    this.initChildren();
                },

                initEvents: function () {
                    if (this.cascade) {
                        this.tree.on('select', this.casadeHandle(true));
                        this.tree.on('unselect', this.casadeHandle(false));
                    }
                    this.searchBox.on('search', u.bind(this.searchHandle, this));
                    this.searchBox.on('clear', u.bind(this.clearSearchHandle, this));

                    if (this.link) {
                        this.link.on('click', u.bind(this.onlinkClick, this));
                    }
                },

                /**
                 * 点击link触发的事件
                 *
                 * @override
                 * @protected
                 */
                onlinkClick: function () {},

                /**
                 * 处理级联
                 *
                 * @override
                 * @protected
                 */
                casadeHandle: function (status) {
                    var tree = this.tree;
                    var handleFunction = status ? 'selectNode' : 'unselectNode';
                    return function (info) {
                        var node = info.node;
                        if (!node || !node.children) {
                            return;
                        }
                        u.each(
                            node.children,
                            function (child) {
                                tree[handleFunction](child.id, false);
                            }
                        );
                    };
                },

                /**
                 * 处理搜索
                 * TODO:目前是本地处理，可以重写或者加方法支持更多的方式。
                 *
                 * @override
                 * @protected
                 */
                searchHandle: function () {
                    var keyword = this.searchBox.getValue();
                    if (keyword === '') {
                        return;
                    }
                    searchText(this.datasource, keyword, this.tree);
                },

                /**
                 * 清除搜索
                 *
                 * @override
                 * @protected
                 */
                clearSearchHandle: function () {
                    searchText(this.datasource, '', this.tree);
                },

                setValue: function (items) {
                    var me = this;
                    u.each(
                        me.tree.nodeIndex,
                        function (node) {
                            var id = node.id;
                            var hasNode = u.find(
                                items,
                                function (item) {
                                    return id === item;
                                }
                            );
                            if (!hasNode) {
                                me.tree.unselectNode(id, true);
                            }
                            else {
                                // tree的isExpanded没有放出来，等放出来之后可以直接用
                                var nodeDom = lib.g(me.tree.helper.getId('node-' + id));
                                if (!isExpanded(me.tree, nodeDom)) {
                                    me.tree.toggleNode(id);
                                }
                                me.tree.selectNode(id, true);
                            }
                        },
                        me
                    );
                },

                getValue: function () {
                    var selecedtNodes = u.map(
                        this.tree.selectedNodeIndex,
                        function (item, key) {
                            return key;
                        }
                    );
                    return selecedtNodes;
                },

                /**
                 * 重渲染
                 *
                 * @method
                 * @protected
                 * @override
                 */
                repaint: painters.createRepaint(
                    Control.prototype.repaint,
                    {
                        /**
                         * @property {meta.TreeItem[]} datasource
                         *
                         * 数据源
                         */
                        name: ['datasource', 'selectedNodes'],
                        paint: function (me, datasource, selectedNodes) {
                            me.tree.setProperties({datasource: datasource});
                            me.setValue(selectedNodes || []);
                        }
                    }
                )
            }
        );

        function buildDOMStructure() {
            var helper = this.helper;
            this.searchBox = new SearchBox({id: helper.getId('searchBox'), buttonPosition: this.buttonPosition});
            this.searchBox.appendTo(this.main);
            if (this.linkContent) {
                this.link = new Button({variants: 'link', content: this.linkContent});
                this.link.appendTo(this.main);
            }
            this.tree = new Tree({
                id: helper.getId('tree'),
                // datasource: this.datasource,
                strategy: this.strategy || new TreeStrategy(),
                wideToggleArea: this.wideToggleArea,
                variants: this.variants,
                selectMode: this.selectMode,
                checkboxes: this.checkboxes,
                selectedNodes: this.selectedNodes,
                hideRoot: this.hideRoot
            });
            this.tree.appendTo(this.main);
        }

         /**
         * 判断一个节点是否展开
         *
         * @param {Tree} tree 控件实例
         * @param {HTMLElement} nodeElement 节点对应的DOM元素
         * @return {boolean}
         * @ignore
         */
        function isExpanded(tree, nodeElement) {
            var className = tree.helper.getPartClasses('node-expanded')[0];
            return $(nodeElement).hasClass(className);
        }

        /**
         * 处理搜索
         *
         * @param {Object} datasource 数据
         * @param {string} keyword 关键词
         * @param {Object} tree 树的控件
         * @return {boolean}
         * @ignore
         */
        function searchText(datasource, keyword, tree) {
            var result = false;

            // 无data直接返回
            if (!datasource) {
                return result;
            }

            if (datasource.text.indexOf(keyword) > -1) {
                result = true;
            }

            if (datasource.children) {
                if (!isExpanded(tree, lib.g(tree.helper.getId('node-' + datasource.id)))) {
                    tree.toggleNode(datasource.id);
                }
                result = u.filter(
                    datasource.children,
                    function (item) {
                        var newKey = result ? '' : keyword;
                        return searchText(item, newKey, tree);
                    }
                );
                result = result.length > 0;
            }

            $(lib.g(tree.helper.getId('node-' + datasource.id))).toggle(result);
            return result;
        }

        esui.register(SearchTree);
        return SearchTree;
    }
);
